﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Text;
using Microsoft.SharePoint.WebPartPages;
using System.Collections.Generic;
using Microsoft.SharePoint.Utilities;
using System.Globalization;

namespace Turners.DMS.WebParts
{
    [ToolboxItemAttribute(false)]
    public class CSVExporter : System.Web.UI.WebControls.WebParts.WebPart
    {
               // Controls
        Button exportbtn = null;
        Button exportAllbtn = null;
        // Hidden controls to record current filter values

        Literal startDateTitle = null;
        Literal endDateTitle = null;
        TextBox startDate = null;
        TextBox endDate = null;

        private string _filePrefix = String.Empty;
        private const string jQueryScriptKey = "jquery";
        private const string jQueryUIScriptKey = "jqueryui";
        private const string jQueryCustomScriptKey = "calendarcustom";

        /// <summary>
        /// The default prefix for the naming of export files
        /// </summary>
        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true),
            WebDisplayName("File name prefix"), WebDescription("The default prefix for the naming of export files.")]
        public string FilePrefix
        {
            get { return _filePrefix; }
            set { _filePrefix = value; }
        }

        public CSVExporter()
        {
            this.PreRender += new EventHandler(CSVExporter_PreRender);
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            startDateTitle = new Literal(){ Text="Start Date: "};
            this.Controls.Add(startDateTitle);

            startDate = new TextBox();
            startDate.ID = "DateStartTextBox";
            startDate.Width = 128;
            this.Controls.Add(startDate);

            endDateTitle = new Literal() { Text = "End Date: " };
            this.Controls.Add(endDateTitle);

            endDate = new TextBox() { ID = "DateEndTextBox", Width = 128 };
            this.Controls.Add(endDate);

            exportbtn = new Button();
            exportbtn.Text = "CSV Export";
            exportbtn.ToolTip = "Creates csv file of documents not yet exported, and within selected date range.";
            exportbtn.Click += new EventHandler(export_Click);
            this.Controls.Add(exportbtn);

            exportAllbtn = new Button();
            exportAllbtn.Text = "CSV Export (All)";
            exportAllbtn.ToolTip = "Creates csv file of ALL documents within selected date range."; 
            exportAllbtn.Click += new EventHandler(exportAll_Click);
            this.Controls.Add(exportAllbtn);

        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            EnsureChildControls();

            // Render some style properties.
            writer.Write(@"
                <style type='text/css'>
                    .exportbtncontainer input {
                        width: 150px;
                        margin: 5px;
                        cursor: pointer;
                        color:#FFFFFF; 
                        font-weight:bold;
                        background-image:url('/_layouts/images/siteactionsmenugrad.gif');
                        background-repeat:repeat-x;
                        border-top:1px solid #6593cf;
                        border-left:1px solid #6593cf;
                        border-right:1px solid #6593cf;
                        background-color:#6593cf;
                        padding:1px 4px 3px 10px; }
                </style>");

            writer.Write(@"<div style='float:left; padding: 20px; '>");
            startDateTitle.RenderControl(writer);
            startDate.RenderControl(writer);
            writer.Write(@"</div>");
            writer.Write(@"<div style='float:left; padding: 20px; '>");
            endDateTitle.RenderControl(writer);
            endDate.RenderControl(writer);
            writer.Write(@"</div>");
            writer.Write(@"<div class='exportbtncontainer' style='float: left; padding: 15px 20px 20px 20px;'>");
            
            // Render all remaining content.
            exportbtn.RenderControl(writer);
            exportAllbtn.RenderControl(writer);
            writer.Write("</div>");
        }


        private void export_Click(object sender, EventArgs e)
        {
            ExportList(false);

        }

        private void exportAll_Click(object sender, EventArgs e)
        {
            ExportList(true);
        }

        public void ExportList( bool includeAll )
        {
            // Find the list we're extracting data from.
            SPList list = SPContext.Current.List;
            if (list == null)
                return;

            // Create CAML Query, Order by date created, do not include Pending documents and documents already exported (optional)
            SPQuery query = new SPQuery();
            query.QueryThrottleMode = SPQueryThrottleOption.Override;
            //query.ViewAttributes = "Scope=\"Recursive\"";

            if (includeAll)
            {
                query.Query = String.Format(@"
                    <OrderBy>
                        <FieldRef Name='DocumentDate' Ascending='True' />
                    </OrderBy>
                   <Where>
                        <And>
                            <Neq>
                                <FieldRef Name='DocumentType' />
                                <Value Type='Choice'>Pending</Value>
                            </Neq>
                            <And>
                                <Geq><FieldRef Name='DocumentDate' />
                                <Value IncludeTimeValue='TRUE' Type='DateTime'>{0}</Value>
                                </Geq>
                                <Leq>
                                    <FieldRef Name='DocumentDate' />
                                    <Value IncludeTimeValue='TRUE' Type='DateTime'>{1}</Value>
                                </Leq>
                            </And>
                        </And>
                    </Where>",
                  !String.IsNullOrEmpty(startDate.Text) ? ConvertToDateTime(startDate.Text) : SPUtility.CreateISO8601DateTimeFromSystemDateTime(new DateTime(2000, 1, 1)),
                  !String.IsNullOrEmpty(endDate.Text) ? ConvertToDateTime(endDate.Text) : SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now));
            }
            else
            {
                query.Query = String.Format(@"
                        <OrderBy>
                          <FieldRef Name='DocumentDate' Ascending='True' />
                       </OrderBy>
                        <Where>
                            <And>
                                <And>
                                    <Geq>
                                        <FieldRef Name='DocumentDate' />
                                        <Value IncludeTimeValue='TRUE' Type='DateTime'>{0}</Value>
                                    </Geq>
                                    <Leq>
                                        <FieldRef Name='DocumentDate' />
                                        <Value IncludeTimeValue='TRUE' Type='DateTime'>{1}</Value>
                                    </Leq>
                                </And>
                                <Eq>
                                    <FieldRef Name='Exported' />
                                    <Value Type='Boolean'>0</Value>
                                </Eq>
                            </And>
                        </Where>",
                    !String.IsNullOrEmpty(startDate.Text) ? ConvertToDateTime(startDate.Text) : SPUtility.CreateISO8601DateTimeFromSystemDateTime(new DateTime(2000, 1, 1)),
                    !String.IsNullOrEmpty(endDate.Text) ? ConvertToDateTime(endDate.Text) : SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now));
            }
            // Extract list items

            SPSecurity.RunWithElevatedPrivileges(delegate()
                                                     {
                     SPListItemCollection items = list.GetItems(query);

                    // Determine default file name
                    string strFileName = FilePrefix + "_" + DateTime.Now.ToShortDateString() + ".csv";

                    // Arrange response content type
                    HttpContext.Current.Response.Clear();
                    HttpContext.Current.Response.ContentType = "Application/x-msexcel";
                    HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=\"" + strFileName + "\"");
                    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);

                    //add the contents of the result set to the response stream
                    HttpContext.Current.Response.Write(GenerateCSV(list, items));
                    HttpContext.Current.Response.End();                                                        
                                                     });


        }

        private string ConvertToDateTime(string strDateTime)
        {
            try
            {
                //dd/MM/YYYY
                DateTimeFormatInfo info = new DateTimeFormatInfo();
                info.ShortDatePattern = "dd/MM/yyyy";
                info.DateSeparator = "/";
                DateTime dt = Convert.ToDateTime(strDateTime, info);
                return dt.ToString("yyyy-MM-dd");
            }
            catch (Exception ex)
            {
                
                throw ex;
            }


        }

        /// <summary>
        /// Generate the csv content based on the list and item collection.
        /// </summary>
        public string GenerateCSV(SPList list, SPListItemCollection items)
        {
            // This is the url of our current list.
            string serverurl = "http://" + System.Environment.MachineName;

            //declare the stringbuilder object that would serve as the placeholder for our data
            StringBuilder sb = new StringBuilder();

            // Create header values.
            sb.Append("Doc Type,Customer No,Customer Name,Document Date,URL\r\n");

            // Append each line
            for( int i = 0; i < items.Count; i++ )
            {
                SPListItem item = items[i];

                try
                {
                    sb.AppendFormat("{0},{1},{2},{3},{4}\r\n",
                        item["DocumentType"].ToString(),
                        (item["CustomerNumber"] == null) ? String.Empty : item["CustomerNumber"].ToString(),
                        (item["CustomerName"] == null) ? String.Empty : item["CustomerName"].ToString(),
                        (item["DocumentDate"] == null) ? String.Empty : item["DocumentDate"].ToString(),
                        (item["FileRef"] == null) ? String.Empty : serverurl + item["FileRef"].ToString());


                    // Flag that this item has been exported.
                    item["Exported"] = true;
                    item.Update();
                }
                catch( Exception ex )
                {
                    // Ignore this item, the flag would not be set.
                    return ex.Message;
                }
            }

            // Return our CSV content
            return sb.ToString();
        }

        public void CSVExporter_PreRender(object sender, EventArgs e)
        {
            ClientScriptManager csm = Page.ClientScript;
            using (SPSite site = new SPSite(SPContext.Current.Site.ID))
            {
                string siteUrl = site.Url;
                if (!siteUrl.EndsWith("/"))
                    siteUrl += "/";
                string scriptFolderUrl = siteUrl + "Style Library/js/";
                string styleFolderUrl = siteUrl + "Style Library/styles/";

                CssLink cssLink = new CssLink();
                cssLink.DefaultUrl = styleFolderUrl + "jquery-calendar-ui.css";
                this.Page.Header.Controls.Add(cssLink);

                if (!csm.IsClientScriptIncludeRegistered(jQueryScriptKey))
                    csm.RegisterClientScriptInclude(jQueryScriptKey, scriptFolderUrl + "jquery.js");
                if (!csm.IsClientScriptIncludeRegistered(jQueryUIScriptKey))
                    csm.RegisterClientScriptInclude(jQueryUIScriptKey, scriptFolderUrl + "jquery-ui.js");
                if (!csm.IsClientScriptIncludeRegistered(jQueryCustomScriptKey))
                    csm.RegisterClientScriptInclude(jQueryCustomScriptKey, scriptFolderUrl + "custom.js");

            }

        }

    }
}
